/*Master 485 bus */
/*Simple HD build 2.0 (build 1.0 didn't worked after trying for a long time)*/ 


#include<avr\io.h>
#include<util\delay.h>
#include<avr\interrupt.h>
#include<avr\eeprom.h>
#include<string.h>
#include<stdlib.h>


/*---------- Defines Macros-------*/
#define PC 1
#define BUS 2 
#define MARK 10
#define RS485_TX PORTB |= (1<<PB2)
#define RS485_RX PORTB &= ~(1<<PB2)
#define TX 9
#define RX 3
#define Address_node 0x0010
#define Message_Address 0x0000
/*----------GLOBAL VARIABLES---------*/
volatile uint8_t r_index,index_t,Bytes_left,MyAddr;

volatile char receive_buffer[100],transmit_buffer[100],Received_packet,toggle,count,t_busy, active, mode;

/*---------FUNCTION DECLARATIONS--------*/

void Usart_Init(void);
void Port_Init(void);
void Timer0_Init(void);
void Mux_Select(char);

void Variable_Init(void);
void usart_puts(char *);
void usart_putchar(char);

void recv_mode(void);
void trans_mode(void);

void send_packet(char *);
void serve(char*);

void packeteer(void);
/* -------- M A I N ------------- */

int main(void)
	{
	Usart_Init();
	Port_Init();
	Variable_Init();
	Timer0_Init();
	packeteer();	
	recv_mode();
	sei();
	
	
		while(1)
		{	
			
			
			
			if(Received_packet == 10)
				{
				serve((char*)receive_buffer);
				
				Received_packet = 0;
				}
			//collect data from nRF24L01+
			
		}
	
	
	
	return 0;
	}
	
	
void Usart_Init(void)
	{
		//UCSRA = 0x00;
		UCSRA |= (1<<MPCM);
		UCSRB = (1<<TXEN)|(1<<TXCIE)|(1<<RXEN)|(1<<UCSZ2);
		UCSRC = (1<<URSEL)|(3<<UCSZ0);
		UBRRH = 0;
		UBRRL = 35;
	}
	
void Port_Init(void)
	{
		DDRB = 0x0F; //PB0 PB1 PB2 are configured as output for MUX MC14016  and MAX485 RO/RE
		PORTB = 0x00; //Initially all ZERO
		
		//PORTB |= (1<<PB2);
	}
void Timer0_Init(void)
	{
		TCCR0 = 0x01;
		TIMSK = 0x01;
	}
void Mux_Select(char char0)
	{
		if(char0 == PC)
			{PORTB &= ~(1<<PB1); PORTB |= (1<<PB0);}
		else if(char0 == BUS)
			{PORTB &= ~(1<<PB0); PORTB |= (1<<PB1); }
		
		_delay_ms(1);	//To stabilize the mux
		
	}
void Variable_Init(void)
	{
		r_index = 0; index_t = 0;
		Received_packet = 0; 
		toggle = 0;
		count = 0;
		t_busy = 0;
		Bytes_left = 0;
		active = 0;
		eeprom_write_block("HI aLL HOW do YOU DO_ARE YOU IN A HURRY_WHERE IS THE TOASTER MACHINE PLANT_END",(uint8_t *)Message_Address,60);
		eeprom_write_byte((uint8_t *)Address_node,0xFF);
	}
	
void usart_puts(char * string0)
	{
		while(!(*string0 == '\0'))
		{
			usart_putchar(*string0);
			string0++;
		}
		while(!(UCSRA & (1<<UDRE)))
		;
		_delay_ms(1);
	}
	
void usart_putchar(char character0)
	{
	while(!(UCSRA & (1<<UDRE)))
	;
		UCSRB &= ~(1<<TXB8);
		UDR = character0;
	}

ISR(USART_RXC_vect)
	{
		
		char temp;
		
		temp = UDR;
		
		PORTB ^= 1;
		
		if(active)
			{
				receive_buffer[r_index++] = temp;
				
				if( temp == '$')
					{	
						r_index = 0;
					}	
				else if (temp == '\n' )
					{
						receive_buffer[r_index] = '\0';
						Received_packet = 10;
						trans_mode();
					}
			}
		else
			{
				if((temp == 1) || (temp == 250) || (temp == 115))
				{
					active = 1;
					UCSRA &= ~(1<<MPCM);
				}
				
			}			
		
	}
	
	
ISR(USART_TXC_vect)
	{
		if(Bytes_left > 0)
			{
				UCSRB |= (1<<TXB8);
				UDR = transmit_buffer[index_t++];
				Bytes_left--;
			}
		else
			{
				t_busy = 0;
				
				recv_mode();
			}
		
	}
	
	
ISR(TIMER0_OVF_vect)
	{
		
		
		(active==1)?(PORTB |= 0x02):(PORTB &= ~0x02);
		
	}

void recv_mode(void)
	{
		RS485_RX;
		UCSRB = (1<<RXEN)|(1<<RXCIE)|(1<<UCSZ2);
		_delay_us(100);
		
	}
	
void trans_mode(void)
	{
		RS485_TX;
		UCSRB = (1<<TXEN)|(1<<TXCIE)|(1<<UCSZ2);
		_delay_us(100);
	}
	
void send_packet(char * ptr)//this functions works when its trans_mode();
	{
		while(t_busy==1)	//wait till last packet is sent
		;
		
		t_busy = 1;
		//Now its fine to start packeting.
		
		index_t = 0;
		transmit_buffer[index_t++]  = '$';
		while((*ptr != '\0') && (*ptr != '\r'))
		transmit_buffer[index_t++] = *ptr++;
		
		transmit_buffer[index_t++] = '\r';
		transmit_buffer[index_t] = '\n';
		
		Bytes_left = index_t;
		
		index_t = 1;
		UDR = transmit_buffer[0];
		
		
	}

void serve(char* ptr2)
	{
		if((strcmp(ptr2,"ping\r\n")) == 0)
		{
			send_packet("ok");	
			UCSRA |= (1<<MPCM);
			active = 0;
		}		
		else if((strcmp(ptr2,"data\r\n")) == 0)
		{
			send_packet("This data From node 1 or 2");	
			//here call function to get data from local eeprom
			UCSRA |= (1<<MPCM);
			active = 0;
		}
		else if((strcmp(ptr2,"imei\r\n")) == 0)
		{
			send_packet("AB7X");	
			UCSRA |= (1<<MPCM);
			active = 0;
		}
		else if((strcmp(ptr2,"func\r\n")) == 0)
		{
			send_packet("Gen Scn Dev");	
			UCSRA |= (1<<MPCM);
			active = 0;
		}		
		else
			{
			send_packet((char *)receive_buffer);
			UCSRA |= (1<<MPCM);
			active = 0;
			}
			
			
	}
	
void packeteer(void)
	{
	uint16_t i;
		cli();
		
		for(i = 0; i <50; i++)
		{
			usart_putchar(eeprom_read_byte((uint8_t*)i));
		}
		sei();//this may cause trouble
		
		
	}